package za.ac.wits.elen7045.scraper.interfaces;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import za.ac.wits.elen7045.enums.DataKey;
import za.ac.wits.elen7045.integrity.checker.interfaces.IntegrityCheckingInterface;
import za.ac.wits.elen7045.persistence.model.ServiceProvider;
import za.ac.wits.elen7045.scraper.models.DataPair;
import za.ac.wits.elen7045.scraper.models.ScraperSession;

/**
 * Interface to define contract for the 3rd party Scraper Service
 * 
 * Since the checker is state less a new entity is created and returned each
 * time.
 * 
 * @author Robert
 */
public abstract class BaseScraper {

	protected BaseScraperMappingEntities scraperMappingEntities;
	protected IntegrityCheckingInterface integrityChecking;
	protected ServiceProvider serviceProvider;

	public BaseScraper(BaseScraperMappingEntities scraperMappingEntities, IntegrityCheckingInterface integrityChecking, ServiceProvider serviceProvider) {
		this.scraperMappingEntities = scraperMappingEntities;
		this.integrityChecking = integrityChecking;
		this.serviceProvider = serviceProvider;
	}
	
	protected ScraperSession scraperSession;
	/**
	 * Initiate scrape on ThirdParty API service
	 * 
	 * @param site
	 * @return
	 */
	public abstract void scrapeSite();
	
	public boolean validateScrape() {
		if (integrityChecking == null)
			return true;
		return integrityChecking.checkScrapedData(scraperSession);
	}

	public HashMap<DataKey, String> getMappedData() throws Exception {
		return scraperMappingEntities.getMappedEntities(scraperSession);
	}
	
	public ScraperSession getScraperSession() {
		return scraperSession;
	}
	
	protected ScraperSession mapXmlToScraperSession(String xml) 
	{
		
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
			InputStream is = new ByteArrayInputStream(xml.getBytes());
			Document doc = docBuilder.parse(is);
			is.close();
			// normalize text representation
			doc.getDocumentElement().normalize();
			System.out.println("Root element of the doc is "
					+ doc.getDocumentElement().getNodeName());

			NodeList baseUrlList = doc.getElementsByTagName("base-url");
            Element baseUrlElement = (Element)baseUrlList.item(0);
            NodeList baseUrlFNList = baseUrlElement.getChildNodes();
            String baseUrl = ((Node)baseUrlFNList.item(0)).getNodeValue().trim();
            
			NodeList dateList = doc.getElementsByTagName("date");
            Element dateElement = (Element)dateList.item(0);
            NodeList dateFNList = dateElement.getChildNodes();
            String date = ((Node)dateFNList.item(0)).getNodeValue().trim();

			NodeList timeList = doc.getElementsByTagName("time");
            Element timeElement = (Element)timeList.item(0);
            NodeList timeFNList = timeElement.getChildNodes();
            String time = ((Node)timeFNList.item(0)).getNodeValue().trim();

            Date scraperDate = new SimpleDateFormat("dd/MM/yyyy H:m:s", Locale.ENGLISH).parse(date + " " + time);
			
			scraperSession = new ScraperSession(scraperDate, baseUrl);


			NodeList listOfDataPairs = doc.getElementsByTagName("datapair");
			int totalDataPairs = listOfDataPairs.getLength();

			for (int s = 0; s < totalDataPairs; s++) {

				Node dataPairNode = listOfDataPairs.item(s);
				if (dataPairNode.getNodeType() == Node.ELEMENT_NODE) {
					Element dataPairElement = (Element)dataPairNode;
					
					NodeList textList = dataPairElement.getElementsByTagName("text");
                    Element textElement = (Element)textList.item(0);

                    NodeList textFNList = textElement.getChildNodes();
                    String text = ((Node)textFNList.item(0)).getNodeValue().trim();

					NodeList valueList = dataPairElement.getElementsByTagName("value");
                    Element valueElement = (Element)valueList.item(0);

                    NodeList valueFNList = valueElement.getChildNodes();
                    String value = ((Node)valueFNList.item(0)).getNodeValue().trim();

                    scraperSession.addDataPair(new DataPair(text, value));
                    
					//System.out.printf("%1$s %2$s", textNode, valueNode);
					// ------

				}// end of if clause

			}
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}
	
}
